package com.cloudbroker.bcs.platform.dav.middle.bizservice.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.cloudbroker.bcs.common.util.DateTimeUtil;
import com.cloudbroker.bcs.common.util.EnumUtil;
import com.cloudbroker.bcs.common.util.StringUtil;
import com.cloudbroker.bcs.common.util.VOUtil;
import com.cloudbroker.bcs.common.util.ValueUtil;
import com.cloudbroker.bcs.common.validatioin.constants.ValidationErrorCodes;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.HSBCPSErrorCodes;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.status.PaySource;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.type.ReChargeType;
import com.cloudbroker.bcs.platform.dav.bizapi.service.base.vo.HSBCPSVO;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.FundBizService;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.result.FuncFundDetailExportResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.result.FundIncomeResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.result.FundListData;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.result.FundListResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.result.FundRewardAmountResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.vo.FundDetailExportForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.vo.FundExportForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.vo.FundListQueryForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.vo.FundUf30ExportForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.fund.vo.QryRewardForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.gold.result.GoldJourData;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.gold.result.UserGoldJourResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.gold.vo.UserGoldJourForm;
import com.cloudbroker.bcs.platform.dav.common.config.ConfigValues;
import com.cloudbroker.bcs.platform.dav.middle.context.HSBCPSBizDataContext;
import com.cloudbroker.bcs.platform.dav.middle.entity.Broker;
import com.cloudbroker.bcs.platform.dav.middle.entity.BrokerManager;
import com.cloudbroker.bcs.platform.dav.middle.entity.FundList;
import com.cloudbroker.bcs.platform.dav.middle.entity.PayWaterCount;
import com.cloudbroker.bcs.platform.dav.middle.entity.PayWaterSumIncome;
import com.cloudbroker.bcs.platform.dav.middle.extservice.gold.GoldService;
import com.cloudbroker.bcs.platform.dav.middle.extservice.uf30.UF30Service;
import com.cloudbroker.bcs.platform.dav.middle.service.BrokerManagerService;
import com.cloudbroker.bcs.platform.dav.middle.service.BrokerService;
import com.cloudbroker.bcs.platform.dav.middle.service.CommonReplyService;
import com.cloudbroker.bcs.platform.dav.middle.service.CustomerService;
import com.cloudbroker.bcs.platform.dav.middle.service.PayWaterService;
import com.cloudbroker.bcs.platform.dav.middle.util.GoldTokenUtil;

@Service
public class FundBizServiceImpl implements FundBizService {
    
    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(FundBizServiceImpl.class);
    
    @Resource
    private PayWaterService payWaterService;
    @Resource
    private CustomerService customerService;
    @Resource
    private CommonReplyService commonReplyService;
    @Resource
    private BrokerService brokerService;
    @Resource
    private UF30Service uf30Service;
    @Resource
    private GoldService goldService;
    @Resource
    private BrokerManagerService brokerManagerService;
    
    @Override
    public FundIncomeResult funcFundIncome(HSBCPSVO param) {
        Long broker_id = HSBCPSBizDataContext.getBrokerId();
        FundIncomeResult fundIncomeVo = new FundIncomeResult();
        
        BigDecimal total_income = ValueUtil.getBigDecimal(payWaterService.countReward(broker_id), BigDecimal.ZERO);
        fundIncomeVo.setTotal_income(total_income);
        BigDecimal day_income = payWaterService.queryTodayRewark(broker_id, null);
        fundIncomeVo.setToday_income(ValueUtil.getBigDecimal(day_income, BigDecimal.ZERO));
        List<PayWaterSumIncome> sumIncomeList = payWaterService.querySumIncomes(broker_id, null, null, null);
        for (PayWaterSumIncome payWaterSumIncome : sumIncomeList) {
            PaySource paySource = EnumUtil.valOf(payWaterSumIncome.getType(), PaySource.class);
            BigDecimal sumAmount = ValueUtil.getBigDecimal(payWaterSumIncome.getSumAmount(), BigDecimal.ZERO);
            switch (paySource) {
                case VIEWPOINT_READ:
                    fundIncomeVo.setViewpoint_income(sumAmount);
                    break;
                case QUESTION:
                    fundIncomeVo.setQuestion_income(sumAmount);
                    break;
                case COMMENT:
                    fundIncomeVo.setChat_income(sumAmount);
                    break;
                case SURVEY:
                    fundIncomeVo.setSurvey_income(sumAmount);
                    break;
                default:
                    break;
            }
        }
        return VOUtil.setSuccessResult(fundIncomeVo);
    }
    
    @Override
    public FundListResult funcFundList(FundListQueryForm param) {
        if (StringUtil.isEmpty(param.getPage_no())) {
            param.setPage_no("1");
        }
        if (StringUtil.isEmpty(param.getPage_count())) {
            param.setPage_count(String.valueOf(ConfigValues.getRequestNum()));
        }
        
        FundListResult fundListResult = new FundListResult();
        Date startTime = null;
        if (StringUtil.isBlank(param.getStart_time())) {
            startTime = HSBCPSBizDataContext.getBroker().getCreate_date();
        } else {
            startTime = DateTimeUtil.toDateOrNull(param.getStart_time(), DateTimeUtil.FORMAT_YYYYMMDD);
        }
        Date endTime = StringUtil.isBlank(param.getEnd_time()) ? null : DateTimeUtil.toDateOrNull(
                param.getEnd_time(), DateTimeUtil.FORMAT_YYYYMMDD);
        if (startTime == null) {
            return VOUtil.genErrorResult(ValidationErrorCodes.PARAM_NOT_DATE, FundListResult.class);
        } else {
            startTime = DateTimeUtil.getStartOfDay(startTime);
        }
        endTime = DateTimeUtil.getEndOfDay(endTime == null ? new Date() : endTime);
        Long brokerId = HSBCPSBizDataContext.getBrokerId();
        String keyword = StringUtil.isBlank(param.getKeyword()) ? null : param.getKeyword();
        PayWaterCount pc = payWaterService.getCounts(brokerId, startTime, endTime, keyword);
        
        Integer counts = pc.getCounts();
        Integer page_no = ValueUtil.getInt(param.getPage_no());
        Integer page_size = ValueUtil.getInt(param.getPage_count(), ConfigValues.getRequestNum());
        List<FundList> list = null;
        if ((ValueUtil.getInt(param.getPage_no()) - 1) * page_size >= counts) {
            //            page_no = (counts + page_size - 1) / page_size;
            list = new ArrayList<>();
        } else {
            if (page_no <= 0) {
                page_no = 1;
            }
            list = payWaterService.queryFundList(brokerId, startTime, endTime, keyword, param.getSort_field(),
                    param.getSort_type(), (page_no - 1) * ValueUtil.getInt(param.getPage_count()), page_size);
        }
        if (page_no == 1) {
            setSumDataToResult(startTime, endTime, brokerId, keyword, fundListResult);
        }
        
        fundListResult.setPage_no(page_no);
        setFundListView(list, fundListResult);
        /*retMap.put("income_list", list);*/
        return VOUtil.setSuccessResult(fundListResult);
    }
    
    @Override
    public FundListResult funcFundExport(FundExportForm param) {
        FundListResult fundListResult = new FundListResult();
        Date startTime = null;
        if (StringUtil.isBlank(param.getStart_time())) {
            startTime = HSBCPSBizDataContext.getBroker().getCreate_date();
        } else {
            startTime = DateTimeUtil.toDateOrNull(param.getStart_time(), DateTimeUtil.FORMAT_YYYYMMDD);
        }
        Date endTime = StringUtil.isBlank(param.getEnd_time()) ? null : DateTimeUtil.toDateOrNull(
                param.getEnd_time(), DateTimeUtil.FORMAT_YYYYMMDD);
        if (startTime == null) {
            return VOUtil.genErrorResult(ValidationErrorCodes.PARAM_NOT_DATE, FundListResult.class);
        } else {
            startTime = DateTimeUtil.getStartOfDay(startTime);
        }
        endTime = DateTimeUtil.getEndOfDay(endTime == null ? new Date() : endTime);
        Long brokerId = HSBCPSBizDataContext.getBrokerId();
        String keyword = StringUtil.isBlank(param.getKeyword()) ? null : param.getKeyword();
        List<FundList> list = payWaterService.queryFundExport(brokerId, startTime, endTime, keyword);
        
        setFundListView(list, fundListResult);
        setSumDataToResult(startTime, endTime, brokerId, keyword, fundListResult);
        fundListResult.setFile_name(DateTimeUtil.toString(startTime, DateTimeUtil.FORMAT_YYYYMMDD) + "-"
                + DateTimeUtil.toString(endTime, DateTimeUtil.FORMAT_YYYYMMDD) + "收入流水");
        
        return VOUtil.setSuccessResult(fundListResult);
    }
    
    @Override
    public FundRewardAmountResult funcQryReward(QryRewardForm param) {
        FundRewardAmountResult fundRewardAmountResult = new FundRewardAmountResult();
        Long broker_id = HSBCPSBizDataContext.getBrokerId();
        if (broker_id == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.ClientErr.NO_SUCH_CLIENT, FundRewardAmountResult.class);
        }
        Integer reward_source = Integer.parseInt(param.getReward_source());
        BigDecimal sumRewark = payWaterService.queryTodayRewark(broker_id, reward_source);
        fundRewardAmountResult.setReward_num(sumRewark.doubleValue());
        
        return VOUtil.setSuccessResult(fundRewardAmountResult);
    }
    
    /*
    * 根据查询结果，设置流水信息
    * */
    private void setFundListView(List<FundList> list, FundListResult fundListView) {
        List<FundListData> fundListDataList = new ArrayList<>();
        for (FundList fundList : list) {
            FundListData fundListData = new FundListData();
            fundListData.setCreate_time(fundList.getCreate_time());
            fundListData.setCustomer_name(fundList.getCustomer_name());
            fundListData.setPosition_str(fundList.getPosition_str());
            fundListData.setReward_amount(fundList.getReward_amount());
            fundListData.setReward_type(fundList.getReward_type());
            fundListData.setMobile_tel(fundList.getMobile_tel());
            fundListDataList.add(fundListData);
        }
        //fundListView.setData_list(fundListDataList);
        fundListView.setIncome_list(fundListDataList);
    }
    
    private void setSumDataToResult(Date startTime, Date endTime, Long brokerId, String keyword,
            FundListResult fundListResult) {
        PayWaterCount pc = payWaterService.getCounts(brokerId, startTime, endTime, keyword);
        if (pc != null) {
            fundListResult.setRecord_count(pc.getCounts());
            fundListResult.setReward_count(pc.getSumamount() == null ? 0 : pc.getSumamount().intValue());
        }
        List<PayWaterSumIncome> sumIncomeList = payWaterService.querySumIncomes(brokerId, startTime, endTime,
                keyword);
        if (sumIncomeList != null) {
            for (PayWaterSumIncome income : sumIncomeList) {
                if (income.getType() != null) {
                    PaySource payType = EnumUtil.valOf(income.getType(), PaySource.class);
                    if (payType == null) {
                        continue;
                    }
                    switch (payType) {
                        case VIEWPOINT_READ:
                            fundListResult.setViewpoint_read(income.getSumAmount());
                            break;
                        case QUESTION:
                            fundListResult.setQuestion(income.getSumAmount());
                            break;
                        case COMMENT:
                            fundListResult.setComment(income.getSumAmount());
                            break;
                        case SURVEY:
                            fundListResult.setSurvey_reward(income.getSumAmount());
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
    
    @Override
    public FuncFundDetailExportResult funcFundDetailExport(FundDetailExportForm param) {
        FuncFundDetailExportResult detailResult = new FuncFundDetailExportResult();
        Broker broker = brokerService.get(param.getBroker_id());
        if (broker == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.ClientErr.NO_SUCH_CLIENT,
                    FuncFundDetailExportResult.class);
        }
        Date startTime = DateTimeUtil.toDateOrNull(param.getStart_time(), DateTimeUtil.FORMAT_YYYYMMDD);
        Date endTime = StringUtil.isBlank(param.getEnd_time()) ? null : DateTimeUtil.toDateOrNull(
                param.getEnd_time(), DateTimeUtil.FORMAT_YYYYMMDD);
        if (startTime == null) {
            return VOUtil.genErrorResult(ValidationErrorCodes.PARAM_NOT_DATE, FuncFundDetailExportResult.class);
        } else {
            startTime = DateTimeUtil.getStartOfDay(startTime);
        }
        endTime = DateTimeUtil.getEndOfDay(endTime == null ? new Date() : endTime);
        List<FundList> list = payWaterService.queryFundExport(broker.getBroker_id(), startTime, endTime, null);
        setSumDataToMap(startTime, endTime, broker.getBroker_id(), null, detailResult);
        List<FundListData> fundListDataList = new ArrayList<>();
        for (FundList fundList : list) {
            FundListData fundListData = new FundListData();
            fundListData.setCreate_time(fundList.getCreate_time());
            fundListData.setCustomer_name(fundList.getCustomer_name());
            fundListData.setPosition_str(fundList.getPosition_str());
            fundListData.setReward_amount(fundList.getReward_amount());
            fundListData.setReward_type(fundList.getReward_type());
            fundListData.setMobile_tel(fundList.getMobile_tel());
            fundListDataList.add(fundListData);
        }
        detailResult.setData_list(fundListDataList);
        detailResult.setBroker_name(broker.getBroker_name());
        detailResult.setStart_date(DateTimeUtil.toString(startTime, DateTimeUtil.FORMAT_YYYYMMDD_NO_BREAK));
        detailResult.setEnd_date(DateTimeUtil.toString(endTime, DateTimeUtil.FORMAT_YYYYMMDD_NO_BREAK));
        return VOUtil.setSuccessResult(detailResult);
    }
    
    private void setSumDataToMap(Date startTime, Date endTime, Long brokerId, String keyword,
            FuncFundDetailExportResult detailResult) {
        PayWaterCount pc = payWaterService.getCounts(brokerId, startTime, endTime, keyword);
        if (pc != null) {
            detailResult.setRecord_count(pc.getCounts());
            detailResult.setReward_count(pc.getSumamount() == null ? 0 : pc.getSumamount().intValue());
        }
        List<PayWaterSumIncome> sumIncomeList = payWaterService.querySumIncomes(brokerId, startTime, endTime,
                keyword);
        if (sumIncomeList != null) {
            for (PayWaterSumIncome income : sumIncomeList) {
                if (income.getType() != null) {
                    PaySource payType = EnumUtil.valOf(income.getType(), PaySource.class);
                    if (payType == null) {
                        continue;
                    }
                    switch (payType) {
                        case VIEWPOINT_READ:
                            detailResult.setViewpoint_read(income.getSumAmount());
                            break;
                        case QUESTION:
                            detailResult.setViewpoint_reward(income.getSumAmount());
                            break;
                        case COMMENT:
                            detailResult.setComment(income.getSumAmount());
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
    
    @Override
    public UserGoldJourResult funcFundUf30ConsumeExport(FundUf30ExportForm param) {
        Broker broker = brokerService.get(param.getBroker_id());
        if (broker == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.ClientErr.NO_SUCH_CLIENT, UserGoldJourResult.class);
        }
        BrokerManager bm = brokerManagerService.getBrokerManager(broker.getBroker_id(), broker.getTenant_id());
        if (bm == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.ClientErr.NO_SUCH_CLIENT, UserGoldJourResult.class);
        }
        List<GoldJourData> consumeList = new ArrayList<GoldJourData>();
        UserGoldJourResult result;
        UserGoldJourForm form = new UserGoldJourForm();
        form.setUser_id(broker.getBroker_key());
        form.setUser_token(GoldTokenUtil.getGoldToken());
        form.setBusiness_type(ReChargeType.INCOME.getVal());
        form.setPage_size(30);
        int i = 1;
        do {
            form.setPage_no(i);
            result = goldService.getUserGoldJour(form);
            if (result != null && result.getData_list() != null) {
                List<GoldJourData> list = result.getData_list();
                consumeList.addAll(list);
            }
            i++;
        } while (result != null && result.getData_list() != null && result.getData_list().size() >= 30);
        if(null == result){
            result = new UserGoldJourResult();
        }
        result.setData_list(consumeList);
        return VOUtil.setSuccessResult(result);
    }
    
    @Override
    public UserGoldJourResult funcFundUf30RechargeExport(FundUf30ExportForm param) {
        Broker broker = brokerService.get(param.getBroker_id());
        if (broker == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.ClientErr.NO_SUCH_CLIENT, UserGoldJourResult.class);
        }
        BrokerManager bm = brokerManagerService.getBrokerManager(broker.getBroker_id(), broker.getTenant_id());
        if (bm == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.ClientErr.NO_SUCH_CLIENT, UserGoldJourResult.class);
        }
        List<GoldJourData> rechargeList = new ArrayList<GoldJourData>();
        UserGoldJourResult result;
        UserGoldJourForm form = new UserGoldJourForm();
        form.setUser_id(broker.getBroker_key());
        form.setUser_token(GoldTokenUtil.getGoldToken());
        form.setBusiness_type(ReChargeType.CHARGE.getVal());
        form.setPage_size(30);
        int i = 1;
        do {
            form.setPage_no(i);
            result = goldService.getUserGoldJour(form);
            if (result != null && result.getData_list() != null) {
                List<GoldJourData> list = result.getData_list();
                rechargeList.addAll(list);
            }
            i++;
        } while (result != null && result.getData_list() != null && result.getData_list().size() >= 30);
        if(null == result){
            result = new UserGoldJourResult();
        }
        result.setData_list(rechargeList);
        return VOUtil.setSuccessResult(result);
    }
}
